#pragma once
#include <iostream>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include "Protocol.hpp"

class TcpClient
{
public:
  TcpClient(std::string ip, int port)
    :_server_ip(ip)
     ,_server_port(port)
     ,_sock(-1)
  {}
  bool TcpClientInit()
  {
    // 创建套接字
    _sock = socket(AF_INET, SOCK_STREAM, 0);
    if (_sock < 0){
      std::cerr << "socket creat fail" << std::endl;
      return false;
    }
    std::cout << "socket creat succes, sock: " << _sock << std::endl;

    return true;
  }

  void TcpClientStart()
  {
    // 连接服务器
    struct sockaddr_in peer;

    peer.sin_family = AF_INET;
    peer.sin_port = htons(_server_port);
    peer.sin_addr.s_addr = inet_addr(_server_ip.c_str());
    
    if (connect(_sock, (struct sockaddr*)&peer, sizeof(peer)) < 0){
      // 连接失败
      std::cerr << "connect fail" << std::endl;
      exit(-1);
    }
    std::cout << "connect success" << std::endl;
    Request();
  }
  void Request()
  {
    std::string msg;
    while (1){
      request rq(0, 0, 0);
      std::cout << "Please Enter first num# ";
      std::cin >> rq._num1;
      std::cout << "Please Enter second num# ";
      std::cin >> rq._num2;
      std::cout << "Please Enter(format:num1(+-*/)num2)# ";
      std::cin >> rq._op;
      
      send(_sock, &rq, sizeof(rq), 0);
      response rp(0, 0);
      ssize_t size = recv(_sock, &rp, sizeof(rp), 0);
      if (size <= 0){
        std::cerr << "read error" << std::endl;
        exit(-1);
      }
      if (rp._code == 1){
        std::cout << "code: " << rp._code << std::endl;
        //std::cout << "除零错误" << std::endl;
      }
      else if (rp._code == 2){
        std::cout << "code: " << rp._code << std::endl;
        //std::cout << "非法操作符" << std::endl;
      }
      else{
        std::cout << "code: " << rp._code << std::endl;
        std::cout << "result: " << rp._result << std::endl;
      }
    }
  }
  ~TcpClient()
  {
    if (_sock >= 0) close(_sock);
  }
private:
  std::string _server_ip;
  int _server_port;
  int _sock;
};
